home *** CD-ROM | disk | FTP | other *** search
/ APDL Other Worlds / APDL Other Worlds Collection.iso / SF3000 / Extras / !SFskyedit / c / Main < prev    next >
Encoding:
Text File  |  2003-11-06  |  13.8 KB  |  459 lines

  1. /*
  2.  *  SFskyedit - Star Fighter 3000 sky colours editor
  3.  *  Main application skeleton
  4.  *  Copyright (C) 2001  Chris Bazley
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public Licence as published by
  8.  *  the Free Software Foundation; either version 2 of the Licence, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public Licence for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public Licence
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* ANSI library files */
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdbool.h>
  25. #include <signal.h>
  26.  
  27. /* RISC OS library files */
  28. #include "kernel.h"
  29. #include "wimp.h"
  30. #include "toolbox.h"
  31. #include "event.h"
  32. #include "wimplib.h"
  33. #include "flex.h"
  34. #include "window.h"
  35.  
  36. /* My library files */
  37. #include "err.h"
  38. #include "msgtrans.h"
  39. #include "hourglass.h"
  40. #include "Macros.h"
  41. #include "Loader.h"
  42. #include "Pal256.h"
  43. #include "ViewsMenu.h"
  44. #include "InputFocus.h"
  45.  
  46. /* Local headers */
  47. #include "SFSIconbar.h"
  48. #include "SFSSaveBox.h"
  49. #include "SFSFileInfo.h"
  50. #include "Menus.h"
  51. #include "Insert.h"
  52. #include "Interpolate.h"
  53. #include "PreQuit.h"
  54. #include "DCS_dialogue.h"
  55. #include "Utils.h"
  56. #include "Main.h"
  57.  
  58. #define WimpVersion    310
  59.  
  60. /* Our toolbox events */
  61. #define EVENT_HELPFILE    0x03
  62. #define EVENT_QUIT        0x09
  63.  
  64. _kernel_oserror  shared_err_block = {255, ""};
  65. int              palette[256];
  66. void            *transtable = NULL; /* flex anchor */
  67. int              x_eigen = 2;
  68. int              y_eigen = 2;
  69. int              x_windlimit = 1023;
  70. int              y_windlimit = 767;
  71. int              scale_factors[4] = {1,1,1,1};
  72. ObjectId         pal256_sharedid = NULL_ObjectId;
  73. char             taskname[32];
  74. bool             format_warning = true;
  75. #ifdef INT_COLOUR_FIND
  76. bool             use_colour_trans = false;
  77. #endif
  78. int              wimp_version;
  79.  
  80. static  WimpPollBlock poll_block;
  81. static  IdBlock       id_block;
  82.  
  83. /* ----------------------------------------------------------------------- */
  84. /*                       Function prototypes                               */
  85.  
  86. static WimpMessageHandler  wimpquit_handler, PreQuit_handler, maketranstable;
  87. static ToolboxEventHandler autocreate_handler, tb_quithandler, error_handler, showhelp_handler;
  88. static WimpEventHandler hide_nontrans_dboxes;
  89. static void initialise(void);
  90. static void process_arguments(int argc, char *argv[]);
  91. static void simple_exit(_kernel_oserror *e);
  92. static void load_cl_files(int argc, char *argv[]);
  93.  
  94. /* ----------------------------------------------------------------------- */
  95. /*                         Public functions                                */
  96.  
  97. int main(int argc, char *argv[])
  98. {
  99.   int event_code;
  100.  
  101.   hourglass_on();
  102.   process_arguments(argc, argv);
  103.   initialise();
  104.   load_cl_files(argc, argv);
  105.   hourglass_off();
  106.  
  107.   /*
  108.    * poll loop
  109.    */
  110.   while (TRUE)
  111.     event_poll (&event_code, &poll_block, 0);
  112. }
  113.  
  114. /* ----------------------------------------------------------------------- */
  115. /*                         Private functions                               */
  116.  
  117. static int maketranstable(WimpMessage *message, void *handle)
  118. {
  119.   void *newptr;
  120.   _kernel_swi_regs regs;
  121.   int vduvarsblock[5];
  122.  
  123.   /* Find required memory for colour translation table */
  124.   regs.r[0] = (int)13; /* source mode */
  125.   regs.r[1] = (int)palette; /* source palette */
  126.   regs.r[2] = -1; /* current mode */
  127.   regs.r[3] = -1; /* current palette */
  128.   regs.r[4] = 0; /* return length needed */
  129.   regs.r[5] = 1; /* R1 = pointer to sprite */
  130.   regs.r[6] = 0;
  131.   regs.r[7] = 0;
  132.   if(!E(_kernel_swi(ColourTrans_GenerateTable, ®s, ®s))) {
  133.     /* Alloc required size */
  134.     if(!flex_alloc((flex_ptr)&newptr, regs.r[4])) {
  135.       RG("NoMem");
  136.     }
  137.     else {
  138.  
  139.       /* Read translation table */
  140.       regs.r[4] = (int)newptr; /* ...other registers preserved */
  141.       if(!E(_kernel_swi(ColourTrans_SelectTable, ®s, ®s))) {
  142.  
  143.         /* Replace current table */
  144.         if(transtable != NULL)
  145.           flex_free((flex_ptr)&transtable);
  146.         flex_reanchor((flex_ptr)&transtable, (flex_ptr)&newptr);
  147.       }
  148.       else
  149.         flex_free((flex_ptr)&newptr);
  150.     }
  151.   }
  152.  
  153.   /* Read eigen factors (OS-to-pixel coordinates scale) */
  154.   vduvarsblock[0] = 4; /* XEigFactor */
  155.   vduvarsblock[1] = 5; /* YEigFactor */
  156.   vduvarsblock[2] = 11; /* XWindLimit */
  157.   vduvarsblock[3] = 12; /* YWindLimit */
  158.   vduvarsblock[4] = -1;
  159.  
  160.   regs.r[0] = (int)&vduvarsblock;
  161.   regs.r[1] = (int)&vduvarsblock;
  162.   if(!E(_kernel_swi(OS_ReadVduVariables, ®s, ®s))) {
  163.     x_eigen = vduvarsblock[0];
  164.     y_eigen = vduvarsblock[1];
  165.     x_windlimit = vduvarsblock[2];
  166.     y_windlimit = vduvarsblock[3];
  167.   }
  168.  
  169.   scale_factors[0] = 2; /* x multiplication factor */
  170.   scale_factors[1] = 2; /* y multiplication factor */
  171.   scale_factors[2] = (1 << x_eigen); /* x division factor */
  172.   scale_factors[3] = (1 << y_eigen); /* y division factor */
  173.  
  174.   return 1; /* claim event */
  175. }
  176.  
  177. /* ----------------------------------------------------------------------- */
  178.  
  179. static int hide_nontrans_dboxes(int event_code, WimpPollBlock *event, IdBlock *id_block, void *handle)
  180. {
  181.   /* We use some psuedo-transient dialogue boxes
  182.      that need closing on mouse-click */
  183.  
  184.   if(id_block->self_id != Interpolate_sharedid
  185.   && id_block->parent_id != Interpolate_sharedid)
  186.     RE(hide_deiconise(Interpolate_sharedid))
  187.  
  188.   if(id_block->self_id != Insert_sharedid
  189.   && id_block->parent_id != Insert_sharedid)
  190.     RE(hide_deiconise(Insert_sharedid))
  191.  
  192.   return 0; /* pass this event on */
  193. }
  194.  
  195. /* ----------------------------------------------------------------------- */
  196.  
  197. static int wimpquit_handler(WimpMessage *message,void *handle)
  198. {
  199.   /* Quit application immediately */
  200.   exit(EXIT_SUCCESS);
  201.  
  202.   return 1; /* claim event */
  203. }
  204.  
  205. /* ----------------------------------------------------------------------- */
  206.  
  207. static int tb_quithandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  208. {
  209.   /* Quit entry on iconbar menu */
  210.   if(TRY_QUIT(0))
  211.     exit(EXIT_SUCCESS);
  212.   return 1; /* claim event */
  213. }
  214.  
  215. /* ----------------------------------------------------------------------- */
  216.  
  217. static int showhelp_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  218. {
  219.   /* Show application help file */
  220.   if(_kernel_oscli("Filer_Run <SFskyedit$Dir>.!Help") == _kernel_ERROR)
  221.     err_check_rep(_kernel_last_oserror());
  222.  
  223.   return 1; /* claim event */
  224. }
  225.  
  226. /* ----------------------------------------------------------------------- */
  227.  
  228. static int PreQuit_handler(WimpMessage *message, void *handle)
  229. {
  230.   int th;
  231.   if(message->hdr.size < 20 || message->data.words[0] == 0)
  232.     th = message->hdr.sender; /* shutdown in progress */
  233.   else
  234.     th = 0; /* just our task */
  235.  
  236.   /* If function returns false then unsaved data */
  237.   if(!TRY_QUIT(th)) {
  238.   
  239.     /* Object by acknowledging message */
  240.     message->hdr.your_ref = message->hdr.my_ref;
  241.     RE(wimp_send_message(Wimp_EUserMessageAcknowledge, message, message->hdr.sender, NULL, NULL))
  242.   }
  243.   return 1; /* claim event */
  244. }
  245.  
  246. /* ----------------------------------------------------------------------- */
  247.  
  248. static int autocreate_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  249. {
  250.   /* Catch auto-created objects and initialise handlers etc. */
  251.   ToolboxObjectAutoCreatedEvent *toace = (ToolboxObjectAutoCreatedEvent *)event;
  252.   if (strcmp(toace->template_name, "Iconbar") == 0) {
  253.     Iconbar_initialise(id_block->self_id);
  254.     return 1; /* claim event */
  255.   }
  256.   if (strcmp(toace->template_name, "PreQuit") == 0) {
  257.     PreQuit_initialise(id_block->self_id);
  258.     return 1; /* claim event */
  259.   }
  260.   if (strcmp(toace->template_name, "Menu") == 0) {
  261.     EF(ViewsMenu_parentcreated(id_block->self_id, 0x03));
  262.     return 1; /* claim event */
  263.   }
  264.   if (strcmp(toace->template_name, "Interpolate") == 0) {
  265.     Interpolate_initialise(id_block->self_id);
  266.     return 1; /* claim event */
  267.   }
  268.   if (strcmp(toace->template_name, "Insert") == 0) {
  269.     Insert_initialise(id_block->self_id);
  270.     return 1; /* claim event */
  271.   }
  272.   if (strcmp(toace->template_name, "ColsMenu") == 0) {
  273.     ColsMenu_initialise(id_block->self_id);
  274.     return 1; /* claim event */
  275.   }
  276.   if (strcmp(toace->template_name, "SkyMenu") == 0) {
  277.     SkyMenu_initialise(id_block->self_id);
  278.     return 1; /* claim event */
  279.   }
  280.   if (strcmp(toace->template_name, "FileMenu") == 0) {
  281.     FileMenu_initialise(id_block->self_id);
  282.     return 1; /* claim event */
  283.   }
  284.   if (strcmp(toace->template_name, "EditMenu") == 0) {
  285.     EditMenu_initialise(id_block->self_id);
  286.     return 1; /* claim event */
  287.   }
  288.   if (strcmp(toace->template_name, "SaveFile") == 0) {
  289.     SaveFile_initialise(id_block);
  290.     return 1; /* claim event */
  291.   }
  292.   if (strcmp(toace->template_name, "FileInfo") == 0) {
  293.     FileInfo_initialise(id_block);
  294.     return 1; /* claim event */
  295.   }
  296.   if (strcmp(toace->template_name, "Pal256") == 0) {
  297.     EF(Pal256_initialise(id_block->self_id));
  298.     EF(event_register_toolbox_handler(id_block->self_id, Window_AboutToBeShown, InputFocus_recordcaretpos, NULL));
  299.     pal256_sharedid = id_block->self_id; /* we only have one palette */
  300.     return 1; /* claim event */
  301.   }
  302.   if (strcmp(toace->template_name, "DCS") == 0) {
  303.     DCS_initialise(id_block->self_id);
  304.     return 1; /* claim event */
  305.   }
  306.  
  307.   return 0; /* event not handled */
  308. }
  309.  
  310. /* ----------------------------------------------------------------------- */
  311.  
  312. static int error_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  313. {
  314.   ToolboxErrorEvent *totee = (ToolboxErrorEvent *)event;
  315.   if(totee->errnum == 0x80b633 || totee->errnum == 0x131c3) /* "To save drag...", locked file */
  316.     err_report(totee->errnum, totee->errmess);
  317.   else
  318.     err_complain(totee->errnum, totee->errmess);
  319.   return 1; /* claim event */
  320. }
  321.  
  322. /* ----------------------------------------------------------------------- */
  323.  
  324. static void initialise(void)
  325. {
  326.   int    toolbox_events = 0,
  327.          wimp_messages = 0;
  328.  
  329.   /*
  330.    * Prevent termination on SIGINT (we use the escape key ourselves)
  331.    */
  332.    signal(SIGINT, SIG_IGN);
  333.  
  334.   /*
  335.    * register ourselves with the Toolbox.
  336.    */
  337.  
  338.   {
  339.     _kernel_oserror *e = toolbox_initialise (0, WimpVersion, &wimp_messages, &toolbox_events, "<SFskyeditRes$Dir>",msgs_get_descriptor(), &id_block, &wimp_version, 0, 0);
  340.     if(e != NULL)
  341.       simple_exit(e);
  342.   }
  343.  
  344.   strncpy(taskname, msgs_lookup("_TaskName"), sizeof(taskname)-1);
  345.   err_set_taskname(taskname, (wimp_version >= 321));
  346.  
  347.   /*
  348.    * initialise the flex library
  349.    */
  350.  
  351.   flex_init(taskname, (int *)msgs_get_descriptor(), 0); /* (use Wimpslot and own messages file) */
  352.   flex_set_budge(1); /* allow budging of flex when heap extends */
  353.  
  354.   /*
  355.    * initialise the event library.
  356.    */
  357.  
  358.   event_initialise (&id_block);
  359.   event_set_mask (Wimp_Poll_NullMask |
  360.                   Wimp_Poll_KeyPressedMask); /* Dealt with by Toolbox */
  361.  
  362.   EF(event_register_toolbox_handler(-1, Toolbox_ObjectAutoCreated, autocreate_handler, NULL));
  363.   EF(event_register_toolbox_handler(-1, Toolbox_Error, error_handler, NULL));
  364.   EF(event_register_toolbox_handler(-1, EVENT_HELPFILE, showhelp_handler, NULL));
  365.   EF(event_register_toolbox_handler(-1, EVENT_QUIT, tb_quithandler, NULL));
  366.  
  367.   EF(event_register_message_handler(Wimp_MPreQuit, PreQuit_handler, NULL));
  368.   EF(event_register_message_handler(Wimp_MQuit, wimpquit_handler, NULL));
  369.   EF(event_register_message_handler(Wimp_MPaletteChange, maketranstable, NULL));
  370.   EF(event_register_message_handler(Wimp_MModeChange, maketranstable, NULL));
  371.   EF(event_register_wimp_handler(-1, Wimp_EMouseClick, hide_nontrans_dboxes, NULL));
  372.  
  373.   EF(InputFocus_initialise());
  374.  
  375.   /* Initialise loader */
  376.   EF(loader_initialise(0));
  377.  
  378.   /* Read the default mode 13 palette */
  379.   {
  380.     _kernel_swi_regs regs;
  381.     regs.r[0] = 13; /* mode 13 */
  382.     regs.r[1] = 0; /* read default palette */
  383.     regs.r[2] = (int)palette; /* pointer to buffer */
  384.     regs.r[3] = sizeof(palette); /* size of buffer */
  385.     regs.r[4] = 0; /* flags */
  386.     EF(_kernel_swi(ColourTrans_ReadPalette, ®s, ®s));
  387.   }
  388.  
  389.   /* Set up translation table to plot mode gfx in current desktop mode */
  390.   maketranstable(NULL, NULL);
  391.  
  392.   EF(ViewsMenu_create());
  393. }
  394.  
  395. /* ----------------------------------------------------------------------- */
  396.  
  397. static void simple_exit(_kernel_oserror *e)
  398. {
  399.   /* Limited amount we can do with no messages file... */
  400.   wimp_report_error(e, Wimp_ReportError_Cancel, "SFskyedit");
  401.   exit(EXIT_FAILURE);
  402. }
  403.  
  404. /* ----------------------------------------------------------------------- */
  405.  
  406. static void process_arguments(int argc, char *argv[])
  407. {
  408.   /*
  409.    * Look at command-line parameters
  410.    */
  411.  
  412.   for(int i = 1; i < argc; i++) {
  413.     if(ViewsMenu_strcmp_nc(argv[i], "-nowarn"))
  414.       format_warning = false;
  415.     else {
  416. #ifdef INT_COLOUR_FIND
  417.       if(ViewsMenu_strcmp_nc(argv[i], "-usect"))
  418.         use_colour_trans = true;
  419.       else {
  420. #endif
  421.         if (*argv[i] == '-') {
  422.           strcpy(shared_err_block.errmess, "Bad command line parameters");
  423.           simple_exit(&shared_err_block);
  424.         }
  425. #ifdef INT_COLOUR_FIND
  426.       }
  427. #endif
  428.     }
  429.   }
  430. }
  431.  
  432. /* ----------------------------------------------------------------------- */
  433.  
  434. static void load_cl_files(int argc, char *argv[])
  435. {
  436.   /*
  437.    * Load any files specified as command-line arguments
  438.    */
  439.  
  440.   for(int i =1; i < argc; i++) {
  441.     /* anything without a '-' in front is interpreted as a file to load */
  442.     if (*argv[i] != '-') {
  443.  
  444.       /* get filetype */
  445.       _kernel_swi_regs regs;
  446.       regs.r[0]=23;
  447.       regs.r[1]=(int)argv[i];
  448.       if(!E(_kernel_swi(OS_File, ®s, ®s))) {
  449.         if(regs.r[6] == FILETYPE_SKYCOLS) {
  450.           void *cl_buffer;
  451.           if(!E(load_compressed(argv[i], (flex_ptr)&cl_buffer)))
  452.             Iconbar_openfile(argv[i], 1, (flex_ptr)&cl_buffer, regs.r[6], NULL);
  453.         }
  454.       }
  455.     } /* parameter is filename */
  456.   } /* next parameter */
  457. }
  458.  
  459.